package com.deer.wms.ware.task.strategy.waveDetail;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.deer.wms.inventory.model.Inventory.Inventory;
import com.deer.wms.inventory.service.InventoryService;
import com.deer.wms.project.root.core.result.CommonCode;
import com.deer.wms.project.root.exception.ServiceException;
import com.deer.wms.system.manage.service.CodeRuleService;
import com.deer.wms.ware.task.model.SO.SoDetail;
import com.deer.wms.ware.task.model.SO.SoMaster;
import com.deer.wms.ware.task.model.Wave.WaveDetail;
import com.deer.wms.ware.task.model.Wave.WaveMaster;
import com.deer.wms.ware.task.model.enums.WaveDetailEnum;
import com.deer.wms.ware.task.model.pickTask.PickTask;
import com.deer.wms.ware.task.service.*;
import com.deer.wms.ware.task.strategy.DetailStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
/**
 * @Author: xu
 * @Date: 2022/08/01/17:14
 * @Description:
 */
public class Picking implements DetailStrategy {
    @Autowired
    private SoDetailService soDetailService;

    @Autowired
    private WaveDetailService waveDetailService;

    @Autowired
    private SoMasterService soMasterService;
    @Autowired
    private CodeRuleService codeRuleService;


    @Autowired
    private WaveMasterService waveMasterService;

    @Autowired
    private PickTaskService pickTaskService;

    @Autowired
    private InventoryService inventoryService;

    //部分分配  1
    @Override
    public Integer getState() {
        return WaveDetailEnum.WAVE_STATE_PICKING.getStatenum();
    }

    @Override
    public void allocation(SoDetail oldSoDetail, SoDetail newDetail, String waveCode) {
        if (newDetail == null) {
            //Step1.老单子是否删除 如果是已经回传ERP.跳出循环
            if (oldSoDetail.getPickQuantity() - oldSoDetail.getOrderQuantity() <= 0) {
                return;
            }
            //Step2.找到对应的波次明细
            WaveDetail waveDetail = waveDetailService.getById(oldSoDetail.getWaveDetailId());
            //Step3.退回源库位，明细行删除
            List<PickTask> pickTasks = pickTaskService.list(new QueryWrapper<PickTask>().eq("so_detail_id", oldSoDetail.getSoDetailId()
                    )
                    .eq("state", 0));
            for (PickTask pickTask : pickTasks) {
                Inventory inventory = inventoryService.getById(pickTask.getInventoryId());
                inventory.setAllotQuantity(inventory.getAllotQuantity() - pickTask.getPickQuantity());
                inventoryService.updateById(inventory);
            }
            //Step4.修改修改波次明细总数量，以及波次明细分配数量
            waveDetail.setQuantity(waveDetail.getQuantity() - oldSoDetail.getOrderQuantity());
            waveDetail.setAllottedQuantity(waveDetail.getAllottedQuantity() - oldSoDetail.getAllottedQuantity());
            soDetailService.removeById(oldSoDetail.getSoDetailId());
            waveDetailService.updateById(waveDetail);
            //如果数量为0删除源单
            if (waveDetail.getQuantity() == 0) {
                waveDetailService.removeById(waveDetail);
            }
        } else if (ObjectUtil.isEmpty(oldSoDetail)) {
            //如果老单子为空则新增一条
            newDetail.setState(0);
            soDetailService.save(newDetail);
            SoMaster soMaster = soMasterService.getOneByField("bill_no", newDetail.getBillNo());
            WaveMaster waveMaster = waveMasterService.getOneByField("code", waveCode);
            WaveDetail waveDetail = new WaveDetail(newDetail);
            waveDetail.setWaveDetailCode(codeRuleService.generateCodeByRedis("waveDetailCode"));
            waveDetail.setRob(newDetail.getRob());
            waveDetail.setQuantity(newDetail.getOrderQuantity());
            waveDetail.setSoMasterId(soMaster.getSoMasterId());
            //波次单信息
            waveDetail.setWaveMasterId(waveMaster.getWaveId());
            waveDetail.setWaveCode(waveMaster.getCode());
            waveDetail.setWareId(waveMaster.getWareId());
            waveDetail.setWareName(waveMaster.getWareName());
            waveDetailService.save(waveDetail);
            newDetail.setWaveDetailId(waveDetail.getWaveDetailId());
            soDetailService.updateById(newDetail);
            waveDetailService.saveOrUpdate(waveDetail);
        } else {
            //都有，则判断数量，有变化则修改
            if (ObjectUtil.notEqual(oldSoDetail.getOrderQuantity(), newDetail.getOrderQuantity())) {
                Double newQty = newDetail.getOrderQuantity();
                Double oldQty = oldSoDetail.getOrderQuantity();
                //新单据数量小于已分配数量
                WaveDetail waveDetail = waveDetailService.getById(oldSoDetail.getWaveDetailId());
                //单据数量使用新单据数量
                oldSoDetail.setOrderQuantity(newQty);
                if (newQty < oldQty) {
                    //退回源库存数量
                    double allQty = oldSoDetail.getAllottedQuantity() - oldSoDetail.getPickQuantity();
                    //调用退回源库位方法
                    this.returnInv(allQty, oldSoDetail);
                    waveDetail.setAllottedQuantity(waveDetail.getAllottedQuantity() - allQty);
                    oldSoDetail.setAllottedQuantity(oldSoDetail.getPickQuantity());
                    soDetailService.updateById(oldSoDetail);
//                    //退回原单重新分配
                    //波次分配数量  = 波次分配数量-任务单明细数量-任务单拣货数量
                }
                waveDetail.setQuantity(waveDetail.getQuantity() + (newDetail.getOrderQuantity() - oldQty));
                soDetailService.updateById(oldSoDetail);
                waveDetailService.updateById(waveDetail);
//                if (true) {
//                    throw new ServiceException(CommonCode.SERVER_INERNAL_ERROR);
//                }

            }
        }


    }


    /**
     * 退回源库位
     * @param allQty
     * @param soDetail
     */
    public void returnInv(Double allQty, SoDetail soDetail) {
        //退回原单重新分配
        List<PickTask> pickTasks = pickTaskService.list(new QueryWrapper<PickTask>()
                .eq("so_detail_id", soDetail.getSoDetailId())
                .eq("state", 0));
        for (PickTask pickTask : pickTasks) {
            //退回数量大于0
            if (allQty == 0) {
                continue;
            }
            //数量退回源库位
            if (allQty >= pickTask.getPickQuantity()) {
                Inventory inventory = inventoryService.getById(pickTask.getInventoryId());
                inventory.setAllotQuantity(inventory.getAllotQuantity() - pickTask.getPickQuantity());
                inventoryService.updateById(inventory);
                pickTaskService.removeById(pickTask.getPickTaskId());
                allQty -= pickTask.getPickQuantity();
            } else {
                Inventory inventory = inventoryService.getById(pickTask.getInventoryId());
                inventory.setAllotQuantity(inventory.getAllotQuantity() - pickTask.getPickQuantity());
                inventoryService.updateById(inventory);
                pickTask.setPickQuantity(pickTask.getPickQuantity() - allQty);
                pickTaskService.updateById(pickTask);
            }

        }
    }
}
